/**
 * outsider.com.cn Inc.
 * Copyright (c) 2011-2022 All Rights Reserved.
 */
package com.yuanmeng.common.core.utils.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;

/**
 * @author outsider
 * @version Id: OssUtils.java, v 0.1 2022/3/25 19:38 Person Exp $$
 */
public class OssUtils {
    private static final Logger log = LoggerFactory.getLogger(OssUtils.class);

    private String              endpoint;

    private String              accessKeyId;

    private String              accessKeySecret;

    private String              bucketName;

    public OssUtils(String endpoint, String bucketName, String accessKeyId,
                    String accessKeySecret) {
        this.endpoint = endpoint;
        this.bucketName = bucketName;
        this.accessKeyId = accessKeyId;
        this.accessKeySecret = accessKeySecret;
    }

    /**
     * 创建存储桶
     */
    public void createBucket() {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 创建存储空间。
            ossClient.createBucket(bucketName);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("创建bucket失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * 上传本地文件至OSS
     *
     * @param filePath 文件路径
     * @param key      唯一key（在oss中的文件名字）
     */
    public void upload(String filePath, String key) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 上传内容到指定的存储空间（bucketName）并保存为指定的文件名称（key）。
            // String content = "Hello OSS";
            // ossClient.putObject(bucketName, key, new ByteArrayInputStream(content.getBytes()));
            ossClient.putObject(bucketName, key, new FileInputStream(new File(filePath)));
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("上传文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * 上传文件，以IO流方式
     *
     * @param inputStream 输入流
     * @param key         唯一key（在oss中的文件名字）
     */
    public void upload(InputStream inputStream, String key) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 上传内容到指定的存储空间（bucketName）并保存为指定的文件名称（key）。
            // String content = "Hello OSS";
            // ossClient.putObject(bucketName, key, new ByteArrayInputStream(content.getBytes()));
            ossClient.putObject(bucketName, key, inputStream);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("上传文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * 上传文件，以IO流方式
     *
     * @param inputStream 输入流
     * @param key         唯一key（在oss中的文件名字）
     */
    public void uploadWechatImg(InputStream inputStream, String key) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(getContentType(""));
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, inputStream);
            putObjectRequest.setMetadata(metadata);
            ossClient.putObject(putObjectRequest);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("上传文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * 上传本地文件至OSS
     *
     * @param file 文件
     * @param key  唯一key（在oss中的文件名字）
     */
    public void upload(File file, String key) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 上传内容到指定的存储空间（bucketName）并保存为指定的文件名称（key）。
            // String content = "Hello OSS";
            // ossClient.putObject(bucketName, key, new ByteArrayInputStream(content.getBytes()));
            ossClient.putObject(bucketName, key, new FileInputStream(file));
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("上传文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * 上传网络文件至OSS
     *
     * @param url 文件url，如：http://www.baidu.com/xxx.jpg
     * @param key 唯一key（在oss中的文件名字）
     */
    public void uploadNetwork(String url, String key) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 上传网络流。
            InputStream inputStream = new URL(url).openStream();
            ossClient.putObject(bucketName, key, inputStream);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("上传网络文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    /**
     * 删除OSS中的文件
     *
     * @param key 唯一key（在oss中的文件名字）
     */
    public void delete(String key) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 删除文件。
            ossClient.deleteObject(bucketName, key);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            log.error("删除文件失败：{}", ExceptionUtils.getStackTrace(e));
            e.printStackTrace();
        }
    }

    public void test() {
        log.info("打印属性endpoint：" + endpoint);
    }

    /**
     * 获取文件地址
     * @param keyName
     * @return
     */
    public String getUrl(String keyName) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 设置URL过期时间为50年  3600l* 1000*24*365*50
        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 50);

        URL url = ossClient.generatePresignedUrl(bucketName, keyName, expiration);
        if (url != null) {
            String urlPath = url.toString();
            if (!urlPath.contains("https")) {
                urlPath = urlPath.replace("http", "https");
            }
            return urlPath;
        }
        return null;
    }

    /**
     * 返回contentType
     * @param FileNameExtension
     * @return
     */
    public static String getContentType(String FileNameExtension) {
        if (FileNameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FileNameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FileNameExtension.equalsIgnoreCase(".jpeg")
            || FileNameExtension.equalsIgnoreCase(".jpg")
            || FileNameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        return "image/jpg";
    }
}
